package com.sczmgk.frame.http;

import android.content.Context;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URLDecoder;
import java.util.HashMap;

public class HttpDownloadRequest extends HttpRequest{
	/**
	 * TAG
	 */
	private final String TAG = "HttpDownloadRequest";
	private final String mSavePath;
	
	private String mSaveFilePath;
	private String mSaveFileName;
	private boolean isNeedContinueDownload = false;
	private final String mFileName;
	private final String mStyleName;
	private final TokenCallback mTokenCallback;
	private DownloadFileSaveUtil.DownloadFileSave mDownloadFileSave;
	
	protected long mContentLength = -1;
	public static final String STYLE_NAME_VIDEO_HIGH = "android_high";
	public static final String STYLE_NAME_VIDEO_LOW = "android_low";
	public static final String STYLE_NAME_VIDEO_NORMAL = "android";

	protected Context mContext;
	
	protected String mCacheXmlUrl;
	public HttpDownloadRequest(Context context, String downloadUrl, String savePath) {
		super(null,HttpRequest.REQUEST_METHOD_GET);
		this.mContext = context;
		this.mSavePath = savePath==null?"":savePath;
		this.mFileName = downloadUrl==null?"":downloadUrl;
		this.mStyleName = "";
		this.mTokenCallback = null;
		this.mCacheXmlUrl = this.mFileName;
	}
	
	public HttpDownloadRequest(Context context, String downloadUrl, String savePath, TokenCallback tokenCallback) {
		super(null,HttpRequest.REQUEST_METHOD_GET);
		this.mContext = context;
		this.mSavePath = savePath==null?"":savePath;
		this.mFileName = downloadUrl==null?"":downloadUrl;
		this.mStyleName = "";
		this.mTokenCallback = tokenCallback;
		this.mCacheXmlUrl = this.mFileName;
	}
	public HttpDownloadRequest(Context context, String downloadUrl, String savePath, String styleName, TokenCallback tokenCallback) {
		super(null,HttpRequest.REQUEST_METHOD_GET);
		this.mContext = context;
		this.mSavePath = savePath==null?"":savePath;
		this.mFileName = downloadUrl==null?"":downloadUrl;
		this.mStyleName = styleName==null?"":styleName;
		this.mTokenCallback = tokenCallback;
		if(!Tools.isEmpty(styleName)){
			this.mCacheXmlUrl = ""+this.mFileName+styleName;
		}else{
			this.mCacheXmlUrl = ""+this.mFileName;
		}
		
	}
	public String getStyleName() {
		return mStyleName;
	}
	public String getSavePath() {
		return mSavePath;
	}
	public String getFileName(){
		return mFileName;
	}
	
	@Override
	public boolean isComplete() {
		if(Tools.isEmpty(mFileName)){
			return false; 
		}
		else if(Tools.isEmpty(mSavePath)){
			return false; 
		}
		return true;
	}


	@Override
	public long getReadTimeout() {
		return 40000;
	}

	@Override
	public long getConnectTimeout() {
		return 40000;
	}


	@Override
	public Object getParamData() {
		return null;
	}


	@Override
	public int getFirstLevel() {
		return mFirstLevel;
	}

	@Override
	public int getRequestType() {
		return HttpRequest.REQUEST_TYPE_DOWNLOAD;
	}

	@Override
	public HttpResponse createErrorResponse(int state, HttpRequest httpTask) {
		return new HttpDownloadResponse(state,httpTask);
	}


	@Override
	public HttpResponse onPreExecute() throws Exception {
		if(!(this instanceof HttpBitmapRequest)){
			String filePath = DownloadFileSaveUtil.getUsableCachePath(mContext, mCacheXmlUrl);
			if(filePath!=null){
				return new HttpDownloadResponse(HttpResponse.STATE_SUCCESS, this, filePath);
			}
		}
		
		if(HttpHelper.hasProtocol(mFileName)){
			if(mStyleName!=null&&mStyleName.length()>0){
				setUrl(mFileName+"/"+mStyleName);
			}else{
				setUrl(mFileName);
			}
			
		}else{
			setUrl(URLDecoder.decode(getTokenStr()));
		}
		return null;
		
	}
	
	private HashMap<String, String> getToken() throws Exception {
		if(mTokenCallback==null){
			return AuthPolicy.getDefaultToken();
		}else{
			HashMap<String, String> tokenMap = mTokenCallback.getToken(this);
			if(tokenMap==null){
				throw new Exception("httpFrame getToken  token ------");
			}
			return tokenMap;
		}
	} 
	
	private String getTokenStr() throws Exception {
		HashMap<String, String> tokenMap = getToken();
		
		if(tokenMap!=null){
			return tokenMap.get(TokenCallback.KEY_TOKEN);
		}
		return null;
		
	}
	public String getCacheUrl(){
		return mCacheXmlUrl;
	}
	
	public String getExtension(HttpURLConnection connection) {
		String field=connection.getHeaderField("Content-Disposition");
		String fileName = "";
		if(field!=null){
			fileName = field.substring(field.indexOf("filename")+10, field.length()-1); 
		}else{
			fileName = getFileName();
		}
		
		return FileUtil.getExtensionName(fileName);
	}
	
	@Override
	public HttpResponse onDoingExecute(HttpURLConnection connection)
			throws Exception {
		InputStream is = connection.getInputStream();
		mContentLength = connection.getContentLength();
		
		InputStream httpInStream = is;
		byte[] buffer = new byte[1024];
		int len = -1;
		int readBytes = 0;
		
		String extension = getExtension(connection);
		
		if(FileUtil.getSDFreeSize(mSavePath)>mContentLength){
			
			if(mSaveFileName != null&&!mSaveFileName.trim().equals("")){
				mSaveFilePath = mSavePath + File.separator+ mSaveFileName;
			}else{
				mSaveFilePath = mSavePath + File.separator+FileUtil.getTimeMillisFileName();
				if(extension!=null&&extension.length()>0){
					mSaveFilePath = mSaveFilePath+"."+extension;
				}
			}
			
			File file=new File(mSaveFilePath);
			file.createNewFile();
			FileOutputStream fos=null;
			try{
				fos = new FileOutputStream(file);
				while ((len = httpInStream.read(buffer)) != -1) {
					readBytes+= len;
					
					fos.write(buffer,0,len);
					HttpThread.postUploadProgress(this, readBytes, mContentLength);
				}
			}catch(Exception ex){
				throw new Exception("涓嬭浇澶辫触   IO娴佸鐞嗗嚭閿�");
			}finally{
				if(fos!=null){
					fos.flush();
					fos.close();
				}
				
			}
			
			return executeContent(mSaveFilePath,extension,readBytes);
		}else{
			if(this instanceof HttpBitmapRequest){
				ByteArrayOutputStream byteArraryStream = new ByteArrayOutputStream();
				while ((len = httpInStream.read(buffer)) != -1) {
					readBytes+= len;
					HttpThread.postUploadProgress(this, readBytes, mContentLength);
					byteArraryStream.write(buffer, 0, len);
				}
				
				byte[] bytes = byteArraryStream.toByteArray();
				
				byteArraryStream.flush();
				byteArraryStream.close();
				
				return executeContent(bytes,extension,readBytes);
			}
			else{
				return new HttpDownloadResponse(HttpResponse.STATE_MEMORY_NOT_ENOUGH, this);
			}
			
			
		}
		
		
		
	}
	
	protected HttpResponse executeContent(byte[] content, String extension, long fileLength){
		String filePath = FileUtil.saveFile(mSavePath, extension, content);
		return executeContent(filePath, extension,fileLength);
	}
	protected HttpResponse executeContent(String filePath, String extension, long fileLength){
		
		DownloadFileSaveUtil.saveFile(mContext, mCacheXmlUrl, 
				new DownloadFileSaveUtil.DownloadFileSave(filePath));
		return new HttpDownloadResponse(HttpResponse.STATE_SUCCESS, this, filePath);
	}
	
	@Override
	public void onPostExecute(boolean isSuccess) {
		if(!isSuccess){
			if(isNeedContinueDownload){
				DownloadFileSaveUtil.saveFile(mContext, mUrl, 
						new DownloadFileSaveUtil.DownloadFileSave(mSaveFilePath, mContentLength)) ;
			}
			
		}
	}
	
	@Override
	public boolean equals(Object o) {
		if(o instanceof HttpDownloadRequest){
			HttpDownloadRequest tempRequest = (HttpDownloadRequest)o;
			if(mFileName.equals(tempRequest.getFileName())&&
				mStyleName.equals(tempRequest.getStyleName())&&
				mSavePath.equals(tempRequest.getSavePath())){
				return true;
			}
		}
		return false;
	}
	
	public void setSaveFileName(String saveFileName){
		mSaveFileName = saveFileName;
		mCacheXmlUrl += saveFileName;
	}

	private void setNeedContinueDownload(boolean isNeedContinueDownload) {
		this.isNeedContinueDownload = isNeedContinueDownload;
	}

	@Override
	public void onPreExecute(HttpURLConnection connection)
			throws Exception {
		mDownloadFileSave = DownloadFileSaveUtil.getFile(mContext, mCacheXmlUrl);
		if(mDownloadFileSave!=null&&
				mDownloadFileSave.getDownloaStatus()== DownloadFileSaveUtil.DownloadFileSave.DOWNLOAD_STATUS_DOWNLOADING){
			connection.setRequestProperty("Range", "bytes="+mDownloadFileSave.mFileLength);
		}
	}
	
}
